package com.example.client.controller;


import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;

import static org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction.oauth2AuthorizedClient;

@RestController
public class DemoController {
    private final WebClient defaultClientWebClient;

    public DemoController(
            @Qualifier("default-client-web-client") WebClient defaultClientWebClient
    ) {
        this.defaultClientWebClient = defaultClientWebClient;
    }

    @GetMapping("demo")
    private String demo() {
        return "demo";
    }
// http://localhost:9111/authorize?grant_type=authorization_code
    @GetMapping(value = "/authorize", params = "grant_type=authorization_code")
    public String authorizationCodeGrant(@RegisteredOAuth2AuthorizedClient("password-client-credentials")
                                         OAuth2AuthorizedClient authorizedClient) {

        String messages = this.defaultClientWebClient
                .get()
                .uri("http://localhost:9526/demo/hello")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve()
                .bodyToMono(String.class)
                .block();
//        model.addAttribute("messages", messages);

        return messages;
    }

    // http://localhost:9111/authorize?grant_type=client_credentials&client_auth=client_secret
    @GetMapping(value = "/authorize", params = {"grant_type=client_credentials", "client_auth=client_secret"})
    public String clientCredentialsGrantUsingClientSecret(@RegisteredOAuth2AuthorizedClient("password-client-credentials")
                                                          OAuth2AuthorizedClient authorizedClient) {

        ClientRegistration clientRegistration = authorizedClient.getClientRegistration();
        System.out.println(clientRegistration.getClientId());
        System.out.println(clientRegistration.getClientSecret());
        System.out.println(authorizedClient.getAccessToken().getTokenValue());

        String messages = this.defaultClientWebClient
                .get()
                .uri("http://localhost:9526/demo/hello")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve()
                .bodyToMono(String.class)
                .block();
        return messages;
    }

    // http://localhost:9111/client/hello
    // 网关访问
    // http://localhost:8080/client/hello
    @GetMapping("hello")
//    public String who(@RegisteredOAuth2AuthorizedClient("password-client-authorization-code")
    public String who(@RegisteredOAuth2AuthorizedClient("password-client-credentials")
    OAuth2AuthorizedClient authorizedClient) {
        String messages = this.defaultClientWebClient
                .get()
//                .uri("http://localhost:9526/demo/hello")
                .uri("http://localhost:9999/resource/demo/hello")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve()
                .bodyToMono(String.class)
                .block();
        return messages;
    }
    // http://localhost:9111/client/hello2

    @GetMapping("hello2")
    public String hello2(@RegisteredOAuth2AuthorizedClient("password-client-authorization-code")
                      OAuth2AuthorizedClient authorizedClient) {
        String messages = this.defaultClientWebClient
                .get()
                .uri("http://localhost:9999/resource/demo/hello")
                .attributes(oauth2AuthorizedClient(authorizedClient))
                .retrieve()
                .bodyToMono(String.class)
                .block();
        return messages;
    }
}
